package be.dch.objectprops;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import be.dch.objectprops.parser.Parser;

import com.google.inject.Inject;

public final class ParserFinderImpl implements ParserFinder {

    private static final Logger LOG = Logger.getLogger(ParserFinderImpl.class);

    private final List<Parser> parserList = new ArrayList<Parser>();

    @Inject
    public ParserFinderImpl(final Set<Parser> parserList) {
	for (final Parser parser : parserList) {
	    this.addParser(parser);
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * be.dch.objectprops.ParserFinder#addParser(be.dch.objectprops.parser.Parser
     * )
     */
    
    public void addParser(final Parser parser) {
	this.parserList.add(parser);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * be.dch.objectprops.ParserFinder#handleAsReader(java.lang.reflect.Field)
     */
    
    public boolean handleAsReader(final Field field) {
	for (final Parser parser : this.parserList) {
	    if (parser.handleAsReader(field)) {
		return true;
	    }
	}
	return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.ParserFinder#handleAsWriter(java.lang.Object)
     */
    
    public boolean handleAsWriter(final Object result) {
	for (final Parser parser : this.parserList) {
	    if (parser.handleAsWriter(result)) {
		return true;
	    }
	}
	return false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.ParserFinder#write(java.lang.Object,
     * java.lang.StringBuilder)
     */
    
    public void write(final Object result, final StringBuilder key) {
	for (final Parser parser : this.parserList) {
	    if ((result != null) && parser.handleAsWriter(result)) {
		ParserFinderImpl.LOG.debug("Handle key " + key.toString() + " with parser: " + parser.getClass());
		parser.write(result, key);
		break;
	    }
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.ParserFinder#read(java.lang.StringBuilder,
     * java.lang.reflect.Field, java.lang.Object)
     */
    
    public void read(final StringBuilder key, final Field field, final Object result) {
	for (final Parser parser : this.parserList) {
	    if (parser.handleAsReader(field)) {
		parser.read(key, field, result);
		break;
	    }
	}
    }

    
    public Object read(final StringBuilder key, final Object result) {
	for (final Parser parser : this.parserList) {
	    if (parser.handleAsReader(null)) {
		return parser.read(key, result);
	    }
	}
	return result;
    }

    
    public void removeParser(final Class<?> clazz) {
	boolean remove = false;
	Parser parserToRemove = null;
	for (final Parser parser : this.parserList) {
	    if (parser.getClass().getName().equals(clazz.getName())) {
		remove = true;
		parserToRemove = parser;
		break;
	    }
	}
	if (remove) {
	    ParserFinderImpl.LOG.debug("Removing parser from list" + clazz.getName());
	    this.parserList.remove(parserToRemove);
	}

    }

}
